package com.neusoft.neuiotms.dcom.converter;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.neusoft.bizcore.auth.common.bean.UserBean;
import com.neusoft.bizcore.web.bean.TreeBean;
import com.neusoft.bizcore.web.support.Searchable;
import com.neusoft.neuiotms.dcom.dto.UserDutyInfoDTO;
import com.neusoft.neuiotms.dcom.service.TeamGroupService;
import com.neusoft.neuiotms.micro.auth.AuthMicroService;

@Component
public class UserAuthorityConditionConverter {

    @Autowired
    private AuthMicroService authMicroService;
    @Autowired
    private TeamGroupService teamGroupService;

    public String searchUserOrgKey = "isUserOrg";
    public String searchUserKey = "isUser";
    public String searchUserFctKey = "isUserFct";

    public Searchable addUserDownOrgCodesAuthoritySearchCondition(final Searchable searchable,
            final UserBean user) {

        if ((searchable.getBooleanValue(this.searchUserOrgKey) != null)
                && searchable.getBooleanValue(this.searchUserOrgKey)) {

            final List<String> orgs = new ArrayList<>();

            final TreeBean orgTree = this.authMicroService.organizationTree().getData();
            final List<TreeBean> treeData = new ArrayList<>();
            treeData.add(orgTree);
            final List<String> userOrgs = user.getOrgs();

            if (CollectionUtils.isNotEmpty(userOrgs)) {

                userOrgs.forEach(orgs::add);

                userOrgs.forEach(k -> {
                    this.currentNode(k, treeData).forEach(orgs::add);
                });
            }

            if (CollectionUtils.isNotEmpty(orgs)) {
                searchable.put("orgCodes", orgs.stream().distinct().collect(Collectors.toList()));
            }
        }

        return searchable;
    }

    public Searchable addUserCodeAuthoritySearchCondition(final Searchable searchable,
            final UserBean user) {

        if ((searchable.getBooleanValue(this.searchUserKey) != null)
                && searchable.getBooleanValue(this.searchUserKey)) {
            searchable.put("userName", user.getUsername());
        }

        return searchable;
    }

    public Searchable addUserFctAuthoritySearchCondition(final Searchable searchable,
            final UserBean user) {

        if ((searchable.getBooleanValue(this.searchUserFctKey) != null)
                && searchable.getBooleanValue(this.searchUserFctKey)) {
            final List<UserDutyInfoDTO> list = this.teamGroupService.dutyInfo(user);
            searchable.put("functionalGroupIds",
                    list.stream().map(k -> k.getFunctionalGroupId()).distinct().collect(Collectors.toList()));
        }

        return searchable;
    }

    private List<String> currentNode(final String orgCode, final List<TreeBean> tree) {
        final List<String> result = new ArrayList<>();
        for (final TreeBean element : tree) {
            if (orgCode.equals(element.getCode())) {
                return this.findChildrenNodeCodes(element.getChildren(), result);
            }
        }
        return result;
    }

    private List<String> findChildrenNodeCodes(final List<TreeBean> tree, final List<String> result) {
        if (CollectionUtils.isNotEmpty(tree)) {
            for (final TreeBean children : tree) {
                result.add(children.getCode());
                if (CollectionUtils.isNotEmpty(children.getChildren())) {
                    this.findChildrenNodeCodes(children.getChildren(), result);
                }
            }
        }

        return result;
    }

}
